package com.atguigu.gmall.rabbit.config;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbit.entiey.GmallCorrelationData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Slf4j
@Component
public class MQProducerAckConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @PostConstruct //构造器执行 就执行init 方法
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    //交换机应答
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            System.out.println("交换机成功应答：" + cause);
        } else {
            System.out.println("交换机应答失败：" + cause);
            retrySendMessage(correlationData);
        }
    }


    //队列应答
    //时机： 只能失败了才应答
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {

        Object uuid = message.getMessageProperties().
                getHeader("spring_returned_message_correlation");
        //重新发送  次数
        String rabbit_prefix = (String) redisTemplate.opsForHash().get("rabbit_prefix", uuid);
        GmallCorrelationData gmallCorrelationData = JSONObject.
                parseObject(rabbit_prefix, GmallCorrelationData.class);
        //判断是否为插件的延迟消息
        if(gmallCorrelationData.isDelay()){
            return;
        }
        //重新发送
        //retrySendMessage(gmallCorrelationData);
    }



    private void retrySendMessage(CorrelationData correlationData) {
        GmallCorrelationData correlationData1 = (GmallCorrelationData) correlationData;
        int retryCount = correlationData1.getRetryCount();
        retryCount++;
        correlationData1.setRetryCount(retryCount);
        if (retryCount <= 2) {

            redisTemplate.opsForHash().put("rabbit_prefix", correlationData1.getId(),
                    JSONObject.toJSONString(correlationData1));
            log.info("成功重新发送:{}" + JSONObject.toJSONString(correlationData1));
            rabbitTemplate.convertAndSend(
                    correlationData1.getExchange(),
                    correlationData1.getRoutingKey(),
                    correlationData1.getMessage(), correlationData1);

        } else {
            log.info("剩余发送次数已经用完:{}" + JSONObject.toJSONString(correlationData1));
        }
    }
}
